package com.run_java_test.test_run;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@RequestMapping("up")
@RestController
public class UploadCodeController3 {
    private final ApplicationContext context;
    private final RequestMappingHandlerMapping handlerMapping;

    private final ConcurrentHashMap<String, Object> dynamicControllers = new ConcurrentHashMap<>();

    @Autowired
    public UploadCodeController3(ApplicationContext context, RequestMappingHandlerMapping handlerMapping) {
        this.context = context;
        this.handlerMapping = handlerMapping;
    }

    @PostMapping("upload")
    public String uploadController(@RequestParam("file") MultipartFile file) {
        try {
            // 自定义的目录路径
            Path customDir = Paths.get("D:\\a2software_cache\\IDEAProject\\self\\java_study_springboot_run_java_source_code\\code_test");
            // 确保目录存在，如果不存在则创建
            if (!Files.exists(customDir)) {
                Files.createDirectories(customDir);
            }
            // 保存源码文件
            Path sourcePath = customDir.resolve(Objects.requireNonNull(file.getOriginalFilename()));
            Files.write(sourcePath, file.getBytes());

            // 编译源码文件
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            int result = compiler.run(null, null, null, sourcePath.toString());
            if (result != 0) {
                return "Compilation failed!";
            }

            // 加载编译后的类
            URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{customDir.toUri().toURL()});
            String className = file.getOriginalFilename().replace(".java", "");
            Class<?> clazz = classLoader.loadClass(className);

            // 去除老的bean
            removeHandlerMappings(className);

            // 创建实例并注册到 Spring 容器中
            Object controllerInstance = clazz.getDeclaredConstructor().newInstance();
            dynamicControllers.put(className, controllerInstance);

            // 更新 Spring 上下文
            registerControllerBean(className, controllerInstance);

            return "Controller uploaded and registered successfully!";
        } catch (Exception e) {
            e.printStackTrace();
            return "Error: " + e.getMessage();
        }
    }

//    // 修改 registerControllerBean 方法
//    private void registerControllerBean(String beanName, Object controllerInstance) {
//        if (context instanceof ConfigurableApplicationContext configurableContext) {
//            ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();
//            // 注册 Bean 到 Spring 容器
//            beanFactory.registerSingleton(beanName, controllerInstance);
//
//            // 更新 RequestMapping
//            handlerMapping.afterPropertiesSet();
//        } else {
//            throw new IllegalStateException("ApplicationContext is not ConfigurableApplicationContext");
//        }
//    }

    private void registerControllerBean(String beanName, Object controllerInstance) {
        if (context instanceof ConfigurableApplicationContext configurableContext) {
            ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();

            // 移除旧的映射（如果有）
            removeHandlerMappings(beanName);

            // 注册新 Bean
            beanFactory.registerSingleton(beanName, controllerInstance);

            // 更新 RequestMapping
            handlerMapping.afterPropertiesSet();
        } else {
            throw new IllegalStateException("ApplicationContext is not ConfigurableApplicationContext");
        }
    }

    private void removeHandlerMappings(String beanName) {
        // 获取所有的映射
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();

        List<RequestMappingInfo> mappingsToRemove = new ArrayList<>();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
            if (entry.getValue().getBean().equals(beanName)) {
                mappingsToRemove.add(entry.getKey());
            }
        }

        // 移除对应的映射
        for (RequestMappingInfo mappingInfo : mappingsToRemove) {
            handlerMapping.unregisterMapping(mappingInfo);
        }
    }
}

//@Configuration
//class AppConfig {
//    @Bean
//    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
//        return new RequestMappingHandlerMapping();
//    }
//}
